package Games.PumpGame
{
	import flash.display.Shape;
	import flash.events.Event;
	import Framework.BaseEntity;
	import Framework.BaseEventHandler;
	import Framework.BaseGame;
	import Framework.BaseGui;
	import Framework.EntityType;
	import Framework.GameHelper;
	import Framework.IntroScreens.BaseMenu;
	import Games.PumpGame.Entities.Avatar;
	import Games.PumpGame.Entities.BaseDevice;
	import Games.PumpGame.Entities.Connection;
	import Games.PumpGame.Entities.Connection;
	import Games.PumpGame.Entities.DeviceInput;
	import Games.PumpGame.Entities.PowerPlant;
	import Games.PumpGame.Entities.Pump;
	import Games.PumpGame.Entities.Room;
	import Games.PumpGame.Entities.Statistics;
	import Games.PumpGame.Entities.TimeBar;
	import Games.PumpGame.Gui.AvatarVisual;
	import Games.PumpGame.Gui.BaseDeviceGui;
	import Games.PumpGame.Gui.DeviceInputGui;
	import Games.PumpGame.Gui.PriceCard;
	import Games.PumpGame.Gui.PumpGui;
	import Games.PumpGame.Gui.RoomGui;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import Framework.KeyEvents.KeyEvent;
	import Games.PumpGame.Gui.StatisticsGui;
	import Games.PumpGame.Gui.TimerBarGui;
	import Games.PumpGame.Menus.IntroText;
	import Games.PumpGame.Menus.MainMenu;
	
	/**
	 * ...
	 * @author Menno
	 */
	public class PumpGame extends BaseGame
	{	
		public static var ROOMSIZE:int = 500;
		public static var CURRENTFUNDS:Number = 100;
		
		public function PumpGame() 
		{
			super();
			eventHandeler = new EventHandler(this);
			
			showMenu();
		}
		
		private function showMenu():void 
		{
			new MainMenu(eventHandeler as EventHandler);
			super.drawLevel();
			
			EventHandler.myDispatcher.addEventListener("INTRO", doIntro);
			
			function doIntro():void
			{
				trace("Intro starting");
				showIntro();
			}
		}
		
		private function showIntro():void 
		{
			guiManager.emptyList();
			
			new IntroText("PumpGame/Texts/IntroText.txt", eventHandeler);

			super.drawLevel();
			trace(numChildren);
			EventHandler.myDispatcher.addEventListener("START", start);
			
			function start():void
			{
				
				startGame();
			}
		}
		
		public function startGame():void
		{
			guiManager.emptyList();
			
			stage.focus = this;
			this.addEventListener(MouseEvent.CLICK, stayFocused);
			
			initLevel();
			addGameEventsListeners();

			startLevel();			
		}
		
		override protected function update(e:Event):void 
		{
			super.update(e);
		}
		
		public function updateCycle(e:Event):void
		{
			var cycleUpdaters:Array = entityManager.getEntitiesOfType(GameEntityType.POWERPLANT);
			for (var i:int = 0; i < cycleUpdaters.length; i++)
			{
				(cycleUpdaters[i] as PowerPlant).updateCycle();
			}			
		}
		
		private function stayFocused(e:MouseEvent):void 
		{
			stage.focus = this;
		}
		
		override protected function initLevel():void
		{
			initRoom();
			
			new Connection(new Pump(new PumpGui(100, 100)), new PowerPlant(new PriceCard(0, 90, 25)));
			new Connection(new Pump(new PumpGui(100, 200)), new PowerPlant(new PriceCard(0, 190, 25)));
		
			new DeviceInput(new BaseDevice(new BaseDeviceGui()),new DeviceInputGui(480, 75));
			
			new Avatar(new AvatarVisual());
			
			new TimeBar(new TimerBarGui(), 10000);
			new Statistics(new StatisticsGui());
			drawLevel();			
		}
		
		public function initRoom():void
		{
			var room:Room = new Room(ROOMSIZE, ROOMSIZE, 30, 30, new RoomGui());
		}
		
		override protected function drawLevel():void 
		{
			super.drawLevel();
			
			graphics.beginFill(0x000000);
			graphics.drawRect(0, 0, 800, 800);
			graphics.endFill();
		}
		
		private function addGameEventsListeners():void
		{
			EventHandler.myDispatcher.addEventListener(KeyEvent.SPACE, doPump);
			EventHandler.myDispatcher.addEventListener("UPDATE", updateCycle);
		}
		
		private function doPump(e:KeyEvent):void 
		{
			var pumps:Array = entityManager.getEntitiesOfType(GameEntityType.PUMP);
			
			//There should be only one avatar
			var avatars:Array = entityManager.getEntitiesOfType(EntityType.CONTROLLABLE);
			var avatar:Avatar = avatars[0];
			
			for (var i:int = 0; i < pumps.length; i++)
			{
				if (GameHelper.getDistance(avatar.guiComponent, pumps[i].guiComponent) <= Pump.range)
				{
					if (avatar.addPump(pumps[i].pumpAmount))
					{
						buyThroughConnection(getConnection(pumps[i]));
					}
					return;
				}	
			}
			
			//Maybe it's for giving energy.
			var inputs:Array = entityManager.getEntitiesOfType(GameEntityType.INPUT);
			
			for (var j:int = 0; j < inputs.length; j++)
			{
				if (GameHelper.getDistance(avatar.guiComponent, (inputs[j] as DeviceInput).guiComponent) <= DeviceInput.inputRange)
				{
					trace ((inputs[j] as DeviceInput).minInput);
					avatar.addPump( -1 * (inputs[j] as DeviceInput).minInput);
					return;
				}
			}
		}
		
		private function buyThroughConnection(connection:Connection):void
		{
			detractFunds(connection.getPowerPlant().priceList[0] * connection.getPump().pumpAmount);
			trace(CURRENTFUNDS);
		}
		
		private function getConnection(connectionEnd:BaseEntity):Connection
		{
			var allConnections:Array = entityManager.getEntitiesOfType(GameEntityType.CONNECTION);
			var connections:Array = new Array();
			
			for (var i:int = 0; i < allConnections.length; i++)
			{
				if ((allConnections[i] as Connection).isConnected(connectionEnd))
				{
					return allConnections[i];
				}
			}
			
			return null;
		}
		
		private function addFunds(value:Number):void
		{
			CURRENTFUNDS += value;
		}
		
		private function detractFunds(value:Number):void
		{
			CURRENTFUNDS -= value;
		}
	}
	
}